summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2022-12-24 03:05:10 +0100
committerGitHub <noreply@github.com>2022-12-24 03:05:10 +0100
commitdb15142ac98f3fbb23fd7b9e952392915e0ed97a (patch)
tree47ecd3fe20d6deef3ac79a8defd6b8d9f0d96066
parentMerge pull request #9486 from liamwhite/shutdown-hell (diff)
parentqt: fix uninitialized memory usage (diff)
downloadyuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.tar
yuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.tar.gz
yuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.tar.bz2
yuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.tar.lz
yuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.tar.xz
yuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.tar.zst
yuzu-db15142ac98f3fbb23fd7b9e952392915e0ed97a.zip
-rw-r--r--src/yuzu/main.cpp63
-rw-r--r--src/yuzu/main.h7
-rw-r--r--src/yuzu/util/overlay_dialog.cpp9
-rw-r--r--src/yuzu/util/overlay_dialog.h1
4 files changed, 65 insertions, 15 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 7ec613669..6121711e0 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1550,8 +1550,9 @@ void GMainWindow::AllowOSSleep() {
bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) {
// Shutdown previous session if the emu thread is still active...
- if (emu_thread != nullptr)
+ if (emu_thread != nullptr) {
ShutdownGame();
+ }
if (!render_window->InitRenderTarget()) {
return false;
@@ -1784,7 +1785,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
OnStartGame();
}
-void GMainWindow::ShutdownGame() {
+void GMainWindow::OnShutdownBegin() {
if (!emulation_running) {
return;
}
@@ -1807,13 +1808,40 @@ void GMainWindow::ShutdownGame() {
emit EmulationStopping();
- // Wait for emulation thread to complete and delete it
- if (system->DebuggerEnabled() || !emu_thread->wait(5000)) {
+ shutdown_timer.setSingleShot(true);
+ shutdown_timer.start(system->DebuggerEnabled() ? 0 : 5000);
+ connect(&shutdown_timer, &QTimer::timeout, this, &GMainWindow::OnEmulationStopTimeExpired);
+ connect(emu_thread.get(), &QThread::finished, this, &GMainWindow::OnEmulationStopped);
+
+ // Disable everything to prevent anything from being triggered here
+ ui->action_Pause->setEnabled(false);
+ ui->action_Restart->setEnabled(false);
+ ui->action_Stop->setEnabled(false);
+}
+
+void GMainWindow::OnShutdownBeginDialog() {
+ shutdown_dialog = new OverlayDialog(this, *system, QString{}, tr("Closing software..."),
+ QString{}, QString{}, Qt::AlignHCenter | Qt::AlignVCenter);
+ shutdown_dialog->open();
+}
+
+void GMainWindow::OnEmulationStopTimeExpired() {
+ if (emu_thread) {
emu_thread->ForceStop();
- emu_thread->wait();
}
+}
+
+void GMainWindow::OnEmulationStopped() {
+ shutdown_timer.stop();
+ emu_thread->disconnect();
+ emu_thread->wait();
emu_thread = nullptr;
+ if (shutdown_dialog) {
+ shutdown_dialog->deleteLater();
+ shutdown_dialog = nullptr;
+ }
+
emulation_running = false;
discord_rpc->Update();
@@ -1859,6 +1887,20 @@ void GMainWindow::ShutdownGame() {
// When closing the game, destroy the GLWindow to clear the context after the game is closed
render_window->ReleaseRenderTarget();
+
+ Settings::RestoreGlobalState(system->IsPoweredOn());
+ system->HIDCore().ReloadInputDevices();
+ UpdateStatusButtons();
+}
+
+void GMainWindow::ShutdownGame() {
+ if (!emulation_running) {
+ return;
+ }
+
+ OnShutdownBegin();
+ OnEmulationStopTimeExpired();
+ OnEmulationStopped();
}
void GMainWindow::StoreRecentFile(const QString& filename) {
@@ -2961,11 +3003,8 @@ void GMainWindow::OnStopGame() {
return;
}
- ShutdownGame();
-
- Settings::RestoreGlobalState(system->IsPoweredOn());
- system->HIDCore().ReloadInputDevices();
- UpdateStatusButtons();
+ OnShutdownBegin();
+ OnShutdownBeginDialog();
}
void GMainWindow::OnLoadComplete() {
@@ -4052,10 +4091,6 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
// Shutdown session if the emu thread is active...
if (emu_thread != nullptr) {
ShutdownGame();
-
- Settings::RestoreGlobalState(system->IsPoweredOn());
- system->HIDCore().ReloadInputDevices();
- UpdateStatusButtons();
}
render_window->close();
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 5b84c7a00..95220b063 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -29,6 +29,7 @@ class GImageInfo;
class GRenderWindow;
class LoadingScreen;
class MicroProfileDialog;
+class OverlayDialog;
class ProfilerWidget;
class ControllerDialog;
class QLabel;
@@ -335,6 +336,10 @@ private slots:
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
void OnLanguageChanged(const QString& locale);
void OnMouseActivity();
+ void OnShutdownBegin();
+ void OnShutdownBeginDialog();
+ void OnEmulationStopped();
+ void OnEmulationStopTimeExpired();
private:
QString GetGameListErrorRemoving(InstalledEntryType type) const;
@@ -384,6 +389,8 @@ private:
GRenderWindow* render_window;
GameList* game_list;
LoadingScreen* loading_screen;
+ QTimer shutdown_timer;
+ OverlayDialog* shutdown_dialog{};
GameListPlaceholder* game_list_placeholder;
diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp
index 3fa3d0afb..796f5bf41 100644
--- a/src/yuzu/util/overlay_dialog.cpp
+++ b/src/yuzu/util/overlay_dialog.cpp
@@ -3,6 +3,7 @@
#include <QKeyEvent>
#include <QScreen>
+#include <QWindow>
#include "core/core.h"
#include "core/hid/hid_types.h"
@@ -162,7 +163,7 @@ void OverlayDialog::MoveAndResizeWindow() {
const auto height = static_cast<float>(parentWidget()->height());
// High DPI
- const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f;
+ const float dpi_scale = parentWidget()->windowHandle()->screen()->logicalDotsPerInch() / 96.0f;
const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
const auto body_text_font_size =
@@ -259,3 +260,9 @@ void OverlayDialog::InputThread() {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
+
+void OverlayDialog::keyPressEvent(QKeyEvent* e) {
+ if (!ui->buttonsDialog->isHidden() || e->key() != Qt::Key_Escape) {
+ QDialog::keyPressEvent(e);
+ }
+}
diff --git a/src/yuzu/util/overlay_dialog.h b/src/yuzu/util/overlay_dialog.h
index 39c44393c..872283d61 100644
--- a/src/yuzu/util/overlay_dialog.h
+++ b/src/yuzu/util/overlay_dialog.h
@@ -94,6 +94,7 @@ private:
/// The thread where input is being polled and processed.
void InputThread();
+ void keyPressEvent(QKeyEvent* e) override;
std::unique_ptr<Ui::OverlayDialog> ui;